﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Net;
using System.Management;
using HostProfiles.Core;

namespace HostProfiles
{
    public partial class FormMain : Form
    {
        string basePath = string.Empty;
        Font baseFont;
        Font boldFont;
        int lastIndex = -1;
        bool goodbye = false;

        public FormMain()
        {
            InitializeComponent();
            basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + Path.DirectorySeparatorChar, "Profiles" + Path.DirectorySeparatorChar);
            baseFont = this.Font;
            boldFont = new Font(baseFont, FontStyle.Bold);
        }

        #region Froms

        private void FormMain_Load(object sender, EventArgs e)
        {
            if (!Directory.Exists(basePath))
            {
                Directory.CreateDirectory(basePath);
            }

            LoadProfiles();
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = !goodbye;
            HideShow();
        }
        #endregion

        #region Buttons
        private void ButtonAdd_Click(object sender, EventArgs e)
        {
            AddProfile(TextBoxName.Text);
        }
        private void ButtonApply_Click(object sender, EventArgs e)
        {
            if (ListViewProfiles.SelectedItems.Count == 0)
            {
                return;
            }

            ApplyProfile();
        }
        private void ButtonFlushDNS_Click(object sender, EventArgs e)
        {
            ExecuteAction(Action.FlushDNS);
        }
        private void ButtonAbout_Click(object sender, EventArgs e)
        {
            ShowAbout();
        }
        private void ButtonExit_Click(object sender, EventArgs e)
        {
            Exit();
        }

        #endregion

        #region Other Controls
        private void TextBoxProfile_TextChanged(object sender, EventArgs e)
        {
            LabelStatus.Text = "";
            ProgressBar.Value = 0;
            ButtonApply.Enabled = true;
            if (ListViewProfiles.SelectedItems.Count == 0) return;
            else
            {
                ListViewProfiles.SelectedItems[0].Tag = TextBoxProfile.Text;
                File.WriteAllText(ListViewProfiles.SelectedItems[0].SubItems[1].Text,
                    ListViewProfiles.SelectedItems[0].Tag.ToString());

            }
        }

        private void ListViewProfiles_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ListViewProfiles.SelectedItems.Count == 0)
            {
                return;
            }

            if (lastIndex == -1)
            {

                TextBoxProfile.Text = ListViewProfiles.SelectedItems[0].Tag.ToString();
                lastIndex = ListViewProfiles.SelectedItems[0].Index;
            }
            else if (lastIndex != ListViewProfiles.SelectedItems[0].Index)
            {
                TextBoxProfile.Text = ListViewProfiles.SelectedItems[0].Tag.ToString();
                lastIndex = ListViewProfiles.SelectedItems[0].Index;
            }


        }

        private void tabPageCurrent_Click(object sender, EventArgs e)
        {
        }

        private void tabControlMain_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (tabControlMain.SelectedIndex)
            {
                case 1:
                    TextBoxHost.Text = ReadHost();
                    break;
                case 2:
                    ExecuteAction(Action.IPConfig);
                    break;
            }
        }

        private void ListViewProfiles_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ApplyProfile();
        }


        #endregion

        #region BackgroundWorker
        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (e.Argument != null)
            {
                Action action = (Action)e.Argument;
                if (action == Action.FlushDNS)
                {
                    Worker(TextBoxMessage, SR.FlushMessage, false, Env.Flush, Env.FlushArg);
                    e.Result = SR.FlushDNSDone;
                }
                else
                {
                    Worker(TextBoxIPs, "{2}", true, Env.Info, Env.InfoArg);
                }
            }
        }

        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ToolStripTop.Enabled = true;
            if (e.Result != null)
            {
                LabelStatus.Text = e.Result.ToString();
            }
            else
            {
                LabelStatus.Text = "Done";
            }
            contextMenuStripProfiles.Enabled = true;
        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            ProgressBar.Value = e.ProgressPercentage;
            MessageAction msg = e.UserState as MessageAction;
            if (msg != null)
            {
                if (msg.Flushed)
                {
                    msg.TextBox.Text = msg.Message.Trim();
                }
                else
                {
                    msg.TextBox.AppendText(msg.Message);
                }
            }
        }

        private void Worker(TextBox callBackTextBox, string callbackMessage, bool flushed, string process, string args)
        {
            try
            {
                backgroundWorker.ReportProgress(0);
                string path = ParseProcess(process);
                MessageAction msg = new MessageAction() { Flushed = flushed, TextBox = callBackTextBox };
                string result = string.Empty;
                if (File.Exists(path))
                {
                    result = ProcessUtil.Execute(path, args, 1000);
                }
                else
                {
                    result = string.Format(SR.CommandNotFound, path, Env.Help);
                }
                msg.Message = string.Format(callbackMessage,
                                                                     DateTime.Now,
                                                                     Environment.NewLine,
                                                                     result,
                                                                     Environment.NewLine);
                backgroundWorker.ReportProgress(50, msg);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            backgroundWorker.ReportProgress(100);
        }

        private static string ParseProcess(string process)
        {
#if WIN
            DirectoryInfo di = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.System));
            string path = string.Format(process, di.FullName);
            return path;
#endif
#if LINUX
			return process;		
#endif
        }
        #endregion

        #region Menu
        private void applyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ButtonApply_Click(this, e);
        }

        private void removeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (ListViewProfiles.SelectedItems.Count == 0)
            {
                return;
            }
            if (MessageBox.Show("Remove profile: " + ListViewProfiles.SelectedItems[0].Text + " ?",
                "Confirm", MessageBoxButtons.YesNo)
                == DialogResult.Yes)
            {
                try
                {
                    File.Delete(ListViewProfiles.SelectedItems[0].SubItems[1].Text);
                    ListViewProfiles.Items.Remove(ListViewProfiles.SelectedItems[0]);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                }
            }
        }

        private void NotifyIconProfiles_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            HideShow();
        }

        private void showToolStripMenuItem_Click(object sender, EventArgs e)
        {
            HideShow();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowAbout();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Exit();
        }


        private void flushDNSToolStripMenuItemSystem_Click(object sender, EventArgs e)
        {
            ExecuteAction(Action.FlushDNS);
        }

        private void flushDNSToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ExecuteAction(Action.FlushDNS);
        }

        void menu_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem menu = sender as ToolStripMenuItem;
            if (menu.Tag != null)
            {
                ListViewItem lv = menu.Tag as ListViewItem;
                lv.Selected = true;
                ApplyProfile();

            }
        }

        #endregion

        #region Private Methods

        private void LoadProfiles()
        {
            ListViewProfiles.Items.Clear();
            string hosts = ReadHost();
            string[] files = Directory.GetFiles(basePath, "*.txt");
            if (files == null || files.Length == 0)
            {
                string current = basePath + "Current.txt";
                File.WriteAllText(current, hosts);
                files = new string[] { current };
            }

            foreach (var file in files)
            {
                AddProfile(hosts, file);
            }


        }

        private void AddProfile(string hosts, string file)
        {
            FileInfo fi = new FileInfo(file);
            string[] info = new string[] { fi.Name.Substring(0, fi.Name.Length - fi.Extension.Length), fi.FullName };
            ListViewItem lv = new ListViewItem(info);
            lv.Tag = File.ReadAllText(fi.FullName);

            ToolStripMenuItem menu = new ToolStripMenuItem(info[0])
            {
                Tag = lv,

            };
            menu.Click += new EventHandler(menu_Click);
            if (lv.Tag.ToString() == hosts)
            {
                lv.Font = boldFont;
                menu.Font = boldFont;
                menu.Image = imageList1.Images[1];
                lv.ImageIndex = 1;

            }
            else
            {
                lv.ImageIndex = 0;
                menu.Image = imageList1.Images[0];

            }
            ListViewProfiles.Items.Add(lv);
            switchProfilesToolStripMenuItem.DropDownItems.Add(menu);


        }

        private void AddProfile(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                toolTipHelp.Show(SR.Profile, this);
                return;
            }
            string file = basePath + name + ".txt";
            try
            {
                if (File.Exists(file))
                {
                    MessageBox.Show("Profile already exist!");
                }
                else
                {
                    File.WriteAllText(file, "");
                    AddProfile(null, file);
                    ListViewProfiles.Items[ListViewProfiles.Items.Count - 1].Selected = true;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }

        private void ApplyProfile()
        {
            foreach (ToolStripMenuItem item in switchProfilesToolStripMenuItem.DropDownItems)
            {
                if (item.Tag != null)
                {
                    ListViewItem lv = item.Tag as ListViewItem;
                    if (lv == ListViewProfiles.SelectedItems[0])
                    {
                        lv.Font = boldFont;
                        lv.ImageIndex = 1;
                        item.Font = boldFont;
                        item.Image = imageList1.Images[1];
                    }
                    else
                    {
                        lv.ImageIndex = 0;
                        lv.Font = baseFont;
                        item.Font = baseFont;
                        item.Image = imageList1.Images[0];
                    }
                }
            }

            if (ListViewProfiles.SelectedItems.Count == 0) return;
            SaveHost(ListViewProfiles.SelectedItems[0].Tag.ToString());
            ExecuteAction(Action.FlushDNS);
            ButtonApply.Enabled = false;
        }

        private string ReadHost()
        {
            string path = ParseProcess(Env.HostPath);
            if (File.Exists(path))
            {
                return File.ReadAllText(path);
            }
            else
            {
                return string.Empty;
            }
        }

        private bool SaveHost(string content)
        {
            string path = ParseProcess(Env.HostPath);
            try
            {
                if (File.Exists(path))
                {
                    File.WriteAllText(path, content);
                    return true;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            return false;

        }

        private void ExecuteAction(Action action)
        {
            LabelStatus.Text = "waiting...";
            ToolStripTop.Enabled = false;
            contextMenuStripProfiles.Enabled = false;
            backgroundWorker.RunWorkerAsync(action);
        }

        private void ShowAbout()
        {
            FormAbout about = new FormAbout();
            about.ShowDialog();
        }

        private void HideShow()
        {
            if (this.Visible)
            {
                this.Hide();
                showToolStripMenuItem.Text = "&Show";
            }
            else
            {
                this.Show();
                showToolStripMenuItem.Text = "&Hide";
            }
        }

        private void Exit()
        {
            goodbye = true;
            Application.Exit();
        }

        #endregion


    }
}
